import { app, BrowserWindow } from 'electron'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import { createMainWindow } from './window'
import { registerIPCHandlers } from './ipc'
import { AppConfig } from './config/app'
import mainLogger from './logger'
import path from 'path'

// 🚫 单实例应用检测 - 防止多开
const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  // 如果获取锁失败，说明已有实例在运行，退出当前实例
  mainLogger.warn('应用已在运行，退出当前实例')
  app.quit()
} else {
  // 当第二个实例尝试启动时，聚焦到第一个实例的窗口
  app.on('second-instance', () => {
    const mainWindow = BrowserWindow.getAllWindows()[0]
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.focus()
      mainLogger.info('检测到第二个实例启动，聚焦到主窗口')
    }
  })
}

// 当 Electron 完成初始化并准备好创建浏览器窗口时，将调用此方法。
// 初始化并准备好创建浏览器窗口。
// 一些 API 只能在事件发生后使用。
// 🛡️ 全局异常处理
process.on('uncaughtException', (error) => {
  mainLogger.error('未捕获的异常', { error: error.message, stack: error.stack })
  // 生产环境下优雅退出
  if (!is.dev) {
    app.quit()
  }
})

process.on('unhandledRejection', (reason, promise) => {
  mainLogger.error('未处理的 Promise 拒绝', { reason, promise })
})

app.whenReady().then(() => {
  mainLogger.info('应用程序启动', { version: app.getVersion() })
  mainLogger.info('日志保存路径', {
    logPath: AppConfig.LOG.DAILY_FOLDER
      ? path.join(AppConfig.LOG.ROOT_DIR, new Date().toISOString().split('T')[0])
      : AppConfig.LOG.ROOT_DIR
  })

  // 设置 Windows 应用用户模型 ID
  electronApp.setAppUserModelId(AppConfig.APP_USER_MODEL_ID)

  // 默认在开发环境中打开或关闭 DevTools 通过 F12
  // 在生产环境中忽略 CommandOrControl + R。
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    // 只在开发环境启用快捷键，生产环境完全禁用
    if (is.dev) {
      optimizer.watchWindowShortcuts(window)
    } else {
      // 生产环境禁用所有开发者工具相关快捷键
      window.webContents.on('before-input-event', (event, input) => {
        // 禁用 F12, Ctrl+Shift+I, Ctrl+Shift+J, Ctrl+U 等开发者工具快捷键
        if (
          input.key === 'F12' ||
          (input.control && input.shift && input.key === 'I') ||
          (input.control && input.shift && input.key === 'J') ||
          (input.control && input.key === 'U')
        ) {
          event.preventDefault()
        }
      })
    }
  })

  // 注册 IPC 处理器
  registerIPCHandlers()

  // 创建主窗口
  createMainWindow()
  mainLogger.info('主窗口创建完成')

  app.on('activate', function () {
    // 在 macOS 上，当点击 dock 图标并没有其他窗口打开时，通常会在应用中重新创建一个窗口。
    // dock 图标被点击并且没有其他窗口打开时，通常会在应用中重新创建一个窗口。
    if (BrowserWindow.getAllWindows().length === 0) {
      createMainWindow()
      mainLogger.info('重新创建主窗口')
    }
  })
})

// 当所有窗口都关闭时，除了 macOS。在 macOS 上，通常应用程序和菜单栏会保持活动状态，直到用户显式退出。
// 应用程序和菜单栏会保持活动状态，直到用户显式退出。
// 通过 Cmd + Q 显式退出。
app.on('window-all-closed', () => {
  mainLogger.info('所有窗口已关闭')
  if (process.platform !== 'darwin') {
    mainLogger.info('应用程序退出')
    app.quit()
  }
})

// 在这个文件中，你可以包含你的应用的特定主进程的代码。你也可以把它们放在单独的文件中，并在这里 require 它们。
// 代码。你也可以把它们放在单独的文件中，并在这里 require 它们。
